% preprocessing module

function [redu_part_names, redu_part_req, redu_part_smoothing_intervals, redu_part_weights] = preprocess(products, part_names, part_req, part_smoothing_intervals, part_weights)

    %m = length(products); % number of distinct end products
    n = size(part_req, 1); % number of distinct parts

    redundant_parts = [];
    
    % fill similarity matrix for parts
    similarity_mx = diag(ones(n, 1));
    for i = 1:n
        
        % parts with constant usage are redundant
        t = part_req(i,:);
        if all(t == t(1))
            redundant_parts = [redundant_parts i];
            continue;
        end
  
        for j = i+1:n
            t = part_req(i,:)./part_req(j,:);
            % check if ratio of part requirements is the same for all parts
            if all(t == t(1)) && part_smoothing_intervals(i) == part_smoothing_intervals(j)
                similarity_mx(i,j) = 1;
                similarity_mx(j,i) = 1;
            end
        end
    end
    
    % compute the list of redundant parts
    % keep only the part whose weight is the largest
    for i = 1:n
        % skip processing if row sums to 1 indicating no similarity
        if sum(similarity_mx(i,:)) == 1
            continue;
        end

        largest_wt_product = i;
        for j = i+1:n
            if similarity_mx(i,j) == 1
                if part_weights(j) > part_weights(largest_wt_product)
                    redundant_parts = [redundant_parts largest_wt_product];
                    largest_wt_product = j;
                else
                    redundant_parts = [redundant_parts j]
                end
            end
        end
    end
    
    % eliminate parts whose parts usage is similar/proportional across end
    % products
    redu_part_smoothing_intervals = []; redu_part_weights = [];
    redu_part_req = []; redu_part_names = [];

    for i = 1:n
        if isempty(redundant_parts) || not(i == redundant_parts)
            redu_part_smoothing_intervals = [redu_part_smoothing_intervals part_smoothing_intervals(i)];
            redu_part_weights = [redu_part_weights part_weights(i)];
            redu_part_req = [redu_part_req; part_req(i,:)];
            redu_part_names = [redu_part_names; part_names(i)];
        end
    end
end